import datetime
import logging
import os
import threading
import time
import tkinter as tk
import uuid
from tkinter import *
import pymysql
import cv2
import numpy as np
import configparser

import wmi
from PIL import Image, ImageTk

content = configparser.ConfigParser()
content.read("./config.ini", encoding='UTF-8')

# 日志参数
log_path = content.get("detect", "log_path")

# mysql参数
sql_ip = content.get("mysql", "sql_ip")
sql_port = eval(content.get("mysql", "sql_port"))
sql_username = content.get("mysql", "sql_username")
sql_password = content.get("mysql", "sql_password")
sql_db = content.get("mysql", "sql_db")
sql_tb_name = content.get("mysql", "sql_tb_name")


# 多线程关联按钮
class MyThread(threading.Thread):
    def __init__(self, func, *args):
        super().__init__()
        self.func = func
        self.args = args
        self.setDaemon(True)
        self.start()  # 在这里开始

    def run(self):
        self.func(*self.args)


# 图像转换
class imgConvert():
    @staticmethod
    def convert(img, resize=False, image_width=640, image_height=480):
        # 将颜色由BGR转为RGB
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = img.astype(np.uint8)
        # 转换成可以显示的图片
        img = Image.fromarray(img)
        # resize图像大小为400x300
        if resize:
            img = img.resize((image_width, image_height),
                             Image.ANTIALIAS)
        img = ImageTk.PhotoImage(img)
        return img


# 按钮显示文字
# noinspection PySimplifyBooleanCheck
class ToolTip(Toplevel):
    def __init__(self, wdgt, msg=None, msgFunc=None, delay=1, follow=True):
        self.wdgt = wdgt
        self.parent = self.wdgt.master  # The parent of the ToolTip is the parent of the ToolTips widget
        Toplevel.__init__(self, self.parent, bg='black', padx=1, pady=1)  # Initalise the Toplevel
        self.withdraw()  # Hide initially
        self.overrideredirect(True)  # The ToolTip Toplevel should have no frame or title bar

        self.msgVar = tk.StringVar()  # The msgVar will contain the text displayed by the ToolTip
        if msg == None:
            self.msgVar.set('No message provided')
        else:
            self.msgVar.set(msg)
        self.msgFunc = msgFunc
        self.delay = delay
        self.follow = follow
        self.visible = 0
        self.lastMotion = 0
        tk.Message(self, textvariable=self.msgVar, bg='#FFFFDD',
                   aspect=1000).grid()  # The test of the ToolTip is displayed in a Message widget
        self.wdgt.bind('<Enter>', self.spawn,
                       '+')  # Add bindings to the widget.  This will NOT override bindings that the widget already has
        self.wdgt.bind('<Leave>', self.hide, '+')
        self.wdgt.bind('<Motion>', self.move, '+')

    def spawn(self, event=None):
        self.visible = 1
        self.after(int(self.delay * 1000), self.show)  # The after function takes a time argument in miliseconds

    def show(self):
        if self.visible == 1 and time.time() - self.lastMotion > self.delay:
            self.visible = 2
        if self.visible == 2:
            self.deiconify()

    def move(self, event):
        self.lastMotion = time.time()
        if self.follow == False:  # If the follow flag is not set, motion within the widget will make the ToolTip dissapear
            self.withdraw()
            self.visible = 1
        self.geometry('+%i+%i' % (
            event.x_root + 10, event.y_root + 10))  # Offset the ToolTip 10x10 pixes southwest of the pointer
        try:
            self.msgVar.set(
                self.msgFunc())  # Try to call the message function.  Will not change the message if the message function is None or the message function fails
        except:
            pass
        self.after(int(self.delay * 1000), self.show)

    def hide(self, event=None):
        self.visible = 0
        self.withdraw()


# 日志类
class LoggerBox(tk.Text):
    def write(self, message):
        self.insert("end", message)
        self.see(tk.END)
        self.update()


# 设置日志系统
def set_logging(rank=-1, verbose=True):
    logging.basicConfig(
        format="%(message)s",
        level=logging.INFO if (verbose and rank in [-1, 0]) else logging.WARN)


# 获得uuid
def get_uuid():
    return uuid.uuid1().hex


# 根据格式需求获取时间
def get_time(time_format="day"):
    now_time = str(datetime.datetime.now())
    sec_time = now_time.split(".")[0]
    day_time = now_time.split(" ")[0]
    if time_format == "day":
        return day_time
    elif time_format == "sec":
        return sec_time


# 获取设备摄像头信息
def get_camrea():
    info = wmi.WMI()
    wql = "Select * From Win32_USBControllerDevice"

    camera_param = ""
    camera_count = 0
    for item in info.query(wql):
        a = item.Dependent.PNPClass
        b = item.Dependent.Name.upper()
        if (a.upper() == 'MEDIA' or a.upper() == 'CAMERA') and 'AUDIO' not in b:
            camera_count += 1
            camera_param += str(item.Dependent) + "\n"

    return camera_param, camera_count


# 输出同时打印日志信息
def console_log(log_box, text, startTime=True):
    global log_path
    # 无日志文件夹，先创建
    if not os.path.exists(log_path):
        os.mkdir(log_path)
    if not isinstance(text, str):
        text = str(text)

    file_name = log_path + get_time(time_format="day") + ".log"
    # 开始加时间
    if startTime:
        text = get_time(time_format="sec") + ": " + text
    # 不换行直接拼接文本内容
    log_box.info(text)
    with open(file_name, 'a+') as f:
        f.write(text)
        f.write('\n')


# 写入数据库
def write_sql(*args):
    # 创建数据库连接
    conn = pymysql.connect(host=sql_ip, port=sql_port, user=sql_username, passwd=sql_password, db=sql_db)
    # 获取一个游标对象
    cursor = conn.cursor()
    # sql语句
    sql = "insert into " + \
          sql_tb_name + \
          " (`id`," \
          "`video_name`," \
          "`video_url`, " \
          "`video_time`, " \
          "`without_mask_flag`, " \
          "`with_mask_flag`, " \
          "`dangerous_level`, " \
          "`video_createTime`, " \
          "`video_modifyTime`) values (%s,%s,%s,%s,%s,%s,%s,%s,%s)"
    # 执行sql
    cursor.execute(sql, (args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8],))
    # 提交
    conn.commit()
    # 关闭连接
    conn.close()
    cursor.close()


# 没有文件夹就创建
def no_exist_create(path):
    if not os.path.exists(path):
        os.mkdir(path)


# 生成日期文件名
def gen_name(suffix=".jpg"):
    now = datetime.datetime.now()
    return now.strftime("%Y%m%d%H%M%S") + suffix


# 保存完整的视频
def save_full_video(out):
    if not out:
        out.release()
